package br.ucb.tcc.persistencia;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import br.ucb.tcc.entidades.Perfil;
import br.ucb.tcc.entidades.Relacionamento;
import br.ucb.tcc.utils.StringUtil;

/**
 * @author italoricci
 * 
 */
public class TwitterDAO {

	static Connection connection;

	static {
		connection = ConnectionFactory.getConnection();
	}

	public static String INSERT_PERFIL = "INSERT INTO PERFIL VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)";
	public static String VERIFICA_PERFIL = "SELECT COUNT(PERFIL.IDPERFIL) FROM PERFIL WHERE PERFIL.IDPERFIL = ?";
	public static String VERIFICAR_RELACOES = "SELECT COUNT(RELACOES.IDPERFILORIGEM) FROM RELACOES WHERE RELACOES.IDPERFILORIGEM = ?";
	public static String UPDATE_PERFIL = "UPDATE PERFIL SET PERFIL.HASHTAGS = ? WHERE PERFIL.IDPERFIL = ?";
	public static String INSERT_RELACOES = "INSERT INTO RELACOES VALUES (?,?,?,?,?,?)";
	public static String BUSCAR_RELACOES = "SELECT RELACOES.IDPERFILORIGEM, RELACOES.NOME, RELACOES.IDDESTINO, RELACOES.NOMEDESTINO, RELACOES.TWEETRELACAO, RELACOES.HASHTAGPESQUISA FROM RELACOES ORDER BY RELACOES.HASHTAGPESQUISA";
	public static String BUSCAR_RELACOES_TAG = "SELECT RELACOES.IDPERFILORIGEM, RELACOES.NOME, RELACOES.IDDESTINO, RELACOES.NOMEDESTINO, RELACOES.TWEETRELACAO, RELACOES.HASHTAGPESQUISA FROM RELACOES";
	public static String BUSCAR_TODOS = "SELECT PERFIL.NOME, PERFIL.SCREENAME, PERFIL.QTDSEGUIDORES, PERFIL.QTDAMIGOS, PERFIL.LOCALIZACAO, PERFIL.ULTIMOTWEET, PERFIL.IDPERFIL FROM PERFIL";
	public static String BUSCAR_PERFIL_ASSUNTO = "SELECT RELACOES.NOME, RELACOES.NOMEDESTINO FROM RELACOES";
	public static String BUSCAR_TAGS_BUSCADAS = "SELECT RELACOES.HASHTAGPESQUISA FROM RELACOES WHERE RELACOES.HASHTAGPESQUISA IS NOT NULL";
	public static String BUSCAR_NOMES_PERFIL = "SELECT PERFIL.SCREENAME FROM PERFIL";

	/**
	 * @param perfilDTO
	 */
	public void inserirPerfil(Perfil perfilDTO) {
		if (verificaRegistroDuplicado(perfilDTO.getId())) {
			try {
				PreparedStatement preparedStatement = connection.prepareStatement(UPDATE_PERFIL);
				preparedStatement.setString(1, perfilDTO.getHashTags());
				preparedStatement.setLong(2, perfilDTO.getId());
				preparedStatement.executeUpdate();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} else {
			PreparedStatement preparedStatement;
			try {
				preparedStatement = connection.prepareStatement(INSERT_PERFIL);
				preparedStatement.setLong(1, perfilDTO.getId());
				preparedStatement.setString(2, perfilDTO.getNomePerfil());
				preparedStatement.setString(3, perfilDTO.getNomeExibicao());
				preparedStatement.setString(4, perfilDTO.getDescricaoPerfil());
				preparedStatement.setString(5, perfilDTO.getLocalizacao());
				preparedStatement.setString(6, perfilDTO.getUrlImagem());
				preparedStatement.setInt(7, perfilDTO.getQtdSeguidores());
				preparedStatement.setInt(8, perfilDTO.getQtdAmigos());
				preparedStatement.setString(9, perfilDTO.getCorFundo());
				preparedStatement.setString(10, perfilDTO.getCorLink());
				preparedStatement.setString(11, perfilDTO.getUrlBackground());
				preparedStatement.setString(12, perfilDTO.getUltimoPost());
				preparedStatement.setString(13, perfilDTO.getHashTags());
				preparedStatement.executeUpdate();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * @param perfis
	 */
	public void inserirPerfis(List<Perfil> perfis) {
		for (Perfil perfil : perfis) {
			inserirPerfil(perfil);
		}
	}

	/**
	 * @param perfil
	 * @return
	 */
	public boolean verificaRegistroDuplicado(Long perfil) {
		try {
			PreparedStatement preparedStatement = connection.prepareStatement(VERIFICA_PERFIL);
			preparedStatement.setLong(1, perfil);
			ResultSet rs = preparedStatement.executeQuery();
			long contador = 0;
			while (rs.next()) {
				contador = rs.getLong(1);
			}
			if (contador > 0) {
				return true;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * @param perfil
	 * @return
	 */
	public boolean verificaRelacoesDuplicadas(Long perfil) {
		try {
			PreparedStatement preparedStatement = connection.prepareStatement(VERIFICAR_RELACOES);
			preparedStatement.setLong(1, perfil);
			ResultSet rs = preparedStatement.executeQuery();
			long contador = 0;
			while (rs.next()) {
				contador = rs.getLong(1);
			}
			if (contador > 0) {
				return true;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * @param relacoesDTO
	 */
	public void inserirRelacoes(Relacionamento relacoesDTO) {
		if (!verificaRelacoesDuplicadas(relacoesDTO.getIdOrigem())) {
			try {
				PreparedStatement preparedStatement = connection.prepareStatement(INSERT_RELACOES);
				preparedStatement.setLong(1, relacoesDTO.getIdOrigem());
				preparedStatement.setString(2, relacoesDTO.getNomeOrigem());
				preparedStatement.setLong(3, relacoesDTO.getIdDestino());
				preparedStatement.setString(4, relacoesDTO.getNomeDestino());
				preparedStatement.setString(5, relacoesDTO.getTweetRelacao());
				preparedStatement.setString(6, relacoesDTO.getHashTagPesquisa());
				preparedStatement.executeUpdate();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * @param perfis
	 */
	public void inserirRelacoes(List<Relacionamento> relacoesDTO) {
		for (Relacionamento rel : relacoesDTO) {
			inserirRelacoes(rel);
		}
	}

	/**
	 * @return
	 */
	public List<Perfil> buscarTodosPerfis() {
		try {
			List<Perfil> perfilDTOs = new ArrayList<Perfil>(0);
			PreparedStatement preparedStatement = connection.prepareStatement(BUSCAR_TODOS + " ORDER BY PERFIL.NOME");
			ResultSet resultSet = preparedStatement.executeQuery();

			while (resultSet.next()) {
				Perfil temp = new Perfil();
				temp.setNomePerfil(resultSet.getString(1));
				temp.setNomeExibicao(resultSet.getString(2));
				temp.setQtdSeguidores(resultSet.getInt(3));
				temp.setQtdAmigos(resultSet.getInt(4));
				temp.setLocalizacao(resultSet.getString(5));
				temp.setUltimoPost(resultSet.getString(6));
				temp.setId(resultSet.getLong(7));
				perfilDTOs.add(temp);
			}
			return perfilDTOs;
		} catch (SQLException e) {
			throw new RuntimeException();
		}
	}

	/**
	 * @return
	 */
	public HashMap<String, String> buscarRelacoes(String hashTag) {
		try {
			PreparedStatement preparedStatement = connection.prepareStatement(BUSCAR_PERFIL_ASSUNTO
					+ " WHERE HASHTAGPESQUISA =  '" + hashTag + "'");
			ResultSet resultSet = preparedStatement.executeQuery();
			HashMap<String, String> relacoes = new HashMap<String, String>();
			while (resultSet.next()) {
				relacoes.put(resultSet.getString(1), resultSet.getString(2));
			}
			return relacoes;
		} catch (SQLException e) {
			throw new RuntimeException();
		}
	}

	/**
	 * @return
	 */
	public List<Relacionamento> buscarTodasRelacoes() {
		try {
			List<Relacionamento> relacoes = new ArrayList<Relacionamento>(0);
			PreparedStatement preparedStatement = connection.prepareStatement(BUSCAR_RELACOES);
			ResultSet resultSet = preparedStatement.executeQuery();

			while (resultSet.next()) {
				Relacionamento temp = new Relacionamento();
				temp.setIdOrigem(resultSet.getLong(1));
				temp.setNomeOrigem(resultSet.getString(2));
				temp.setIdDestino(resultSet.getLong(3));
				temp.setNomeDestino(resultSet.getString(4));
				temp.setTweetRelacao(resultSet.getString(5));
				temp.setHashTagPesquisa(resultSet.getString(6));
				relacoes.add(temp);
			}
			return relacoes;
		} catch (SQLException e) {
			throw new RuntimeException();
		}
	}

	/**
	 * @return
	 */
	public List<Relacionamento> buscarRelacoesPorTags(String tag) {
		try {
			List<Relacionamento> relacoes = new ArrayList<Relacionamento>(0);
			StringBuilder sb = new StringBuilder(BUSCAR_RELACOES_TAG);
			if (tag != null && !tag.equals("")) {
				sb.append(" WHERE RELACOES.HASHTAGPESQUISA =  '" + tag + "'");
			}
			sb.append(" ORDER BY RELACOES.HASHTAGPESQUISA");
			PreparedStatement preparedStatement = connection.prepareStatement(sb.toString());
			ResultSet resultSet = preparedStatement.executeQuery();

			while (resultSet.next()) {
				Relacionamento temp = new Relacionamento();
				temp.setIdOrigem(resultSet.getLong(1));
				temp.setNomeOrigem(resultSet.getString(2));
				temp.setIdDestino(resultSet.getLong(3));
				temp.setNomeDestino(resultSet.getString(4));
				temp.setTweetRelacao(resultSet.getString(5));
				temp.setHashTagPesquisa(resultSet.getString(6));
				relacoes.add(temp);
			}
			return relacoes;
		} catch (SQLException e) {
			throw new RuntimeException();
		}
	}

	public Set<String> buscarTagsPesquisadas() {
		try {
			Set<String> tagsPesquisadas = new HashSet<String>(0);
			PreparedStatement preparedStatement = connection.prepareStatement(BUSCAR_TAGS_BUSCADAS);
			ResultSet resultSet = preparedStatement.executeQuery();

			while (resultSet.next()) {
				tagsPesquisadas.add(resultSet.getString(1));
			}
			return tagsPesquisadas;
		} catch (SQLException e) {
			throw new RuntimeException();
		}
	}

	public List<String> buscarPerfis() {
		try {
			List<String> perfis = new ArrayList<String>(0);
			PreparedStatement preparedStatement = connection.prepareStatement(BUSCAR_NOMES_PERFIL
					+ " ORDER BY PERFIL.NOME");
			ResultSet resultSet = preparedStatement.executeQuery();

			while (resultSet.next()) {
				perfis.add(resultSet.getString(1));
			}
			return perfis;
		} catch (SQLException e) {
			throw new RuntimeException();
		}
	}

	/**
	 * @param nome
	 * @param screenName
	 * @param qtdAmigos
	 * @param qtdSeguidores
	 * @param localizacao
	 * @param trechoPost
	 * @return
	 * @throws NumberFormatException
	 */
	public List<Perfil> buscarPorCriterio(String nome, String screenName, String qtdAmigos, String qtdSeguidores,
			String localizacao, String trechoPost) throws NumberFormatException {
		try {
			StringBuilder sql = new StringBuilder(BUSCAR_TODOS + " WHERE 1=1");

			if (!StringUtil.isStringVazia(nome)) {
				sql.append(" AND PERFIL.NOME LIKE '% ").append(nome).append(" %'");
			}
			if (!StringUtil.isStringVazia(screenName)) {
				sql.append(" AND PERFIL.SCREENAME LIKE '%").append(screenName).append("%'");
			}
			if (!StringUtil.isStringVazia(qtdSeguidores) && Integer.valueOf(qtdSeguidores) > 0) {
				sql.append(" AND PERFIL.QTDSEGUIDORES >").append(Integer.valueOf(qtdSeguidores));
			}
			if (!StringUtil.isStringVazia(qtdAmigos) && Integer.valueOf(qtdAmigos) > 0) {
				sql.append(" AND PERFIL.QTDAMIGOS > ").append(Integer.valueOf(qtdAmigos));
			}
			if (!StringUtil.isStringVazia(localizacao)) {
				sql.append(" AND PERFIL.LOCALIZACAO LIKE '%").append(localizacao).append("%'");
			}
			if (!StringUtil.isStringVazia(trechoPost)) {
				sql.append(" AND PERFIL.ULTIMOTWEET LIKE '%").append(trechoPost).append("%'");
			}

			sql.append(" ORDER BY PERFIL.NOME");

			List<Perfil> perfilDTOs = new ArrayList<Perfil>(0);
			PreparedStatement preparedStatement = connection.prepareStatement(sql.toString());
			ResultSet resultSet = preparedStatement.executeQuery();

			while (resultSet.next()) {
				Perfil temp = new Perfil();
				temp.setNomePerfil(resultSet.getString(1));
				temp.setNomeExibicao(resultSet.getString(2));
				temp.setQtdSeguidores(resultSet.getInt(3));
				temp.setQtdAmigos(resultSet.getInt(4));
				temp.setLocalizacao(resultSet.getString(5));
				temp.setUltimoPost(resultSet.getString(6));
				temp.setId(resultSet.getLong(7));
				perfilDTOs.add(temp);
			}
			return perfilDTOs;
		} catch (SQLException e) {
			throw new RuntimeException(e.getMessage());
		} catch (NumberFormatException e) {
			throw new NumberFormatException("Favor informar um n�mero para pesquisa.");
		}
	}
}
